/*
 * Copyright 2009 Jiwei Xu (http://www.xujiwei.com)
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

provide("LayoutContainer");

LayoutContainer = Class({
    "static" : {
        Count : 0
    },

    Initialize : function(canvas, name) {
        LayoutContainer.Count++;

        // private properties
        this.objects = [];
        this.canvas = canvas.cloneNode(false);
        this.context = this.canvas.getContext("2d");
        this.size = { Width : canvas.width, Height : canvas.height };

        // public properties
        this.Visible = true;
        this.Name = name || "Layout " + LayoutContainer.Count;
        this.ID   = "LAYOUT" + LayoutContainer.Count;
        this.Alpha = 1;
        this.Composite = "source-over";
        this.IsSelected = false;
        this.NeedUpdate = false;
    },

    SetSize : function(w, h) {
        this.size.Width = w;
        this.size.Height = h;
    },

    GetObjects : function() {
        return this.objects;
    },

    GetSelectedObjects : function() {
        var ret = [];
        for (var i = 0; i < this.objects.length; ++i) {
            if (this.objects[i].IsSelected) {
                ret.push(this.objects[i]);
            }
        }

        return ret;
    },

    ObjectAt : function(p) {
        for (var i = this.objects.length - 1; i >= 0; --i) {
          if (this.objects[i].HitTest(p)) {
              return this.objects[i];
          }
        }

        return null;
    },

    GetFirstObject : function() {
        return this.objects[0] || null;
    },

    GetLastObject : function() {
        return this.objects.length > 0 ? this.objects[this.objects.length - 1] : null;
    },

    Contains : function(obj) {
        var found = false;
        for (var i = 0; i < this.objects.length; ++i) {
            if (this.objects[i] == obj) {
                found = true;
                break;
            }
        }

        return found;
    },

    AddHead : function(obj) {
        if (!this.Contains(obj)) {
            this.objects.unshift(obj);
        }
    },

    Add : function(obj) {
        if (!this.Contains(obj)) {
            this.objects.push(obj);
        }
    },

    Remove : function(obj) {
        for (var i = 0; i < this.objects.length; ++i) {
            if (this.objects[i] == obj) {
                this.objects.splice(i, 1);
                break;
            }
        }
    },

    RemoveAll : function() {
        this.objects.splice(0, this.objects.length);
    },

    Draw : function(view) {
        if (this.Visible) {
            var ctx = this.context, objs = this.objects;

            if (this.IsSelected || this.NeedUpdate) {
                ctx.clearRect(0, 0, this.size.Width, this.size.Height);

                for (var i = 0; i < objs.length; ++i) {

                    var obj = objs[i];

                    ctx.save();
                    obj.Draw(ctx);
                    if (obj.IsSelected) {
                        obj.DrawHandles(ctx);
                    }
                    ctx.restore();
                }

                this.NeedUpdate = false;
            }

            view.Context.drawImage(this.canvas, 0, 0);
        }
    },

    GetDataURL : function(width, height) {
        var data = "";
        try {
            data = this.canvas.toDataURL("image/png");
        } catch (e) {
        }

        return data;
    },

    Select : function(obj, add) {
        if (!add) {
            this.SelectNone();
        }
        obj.IsSelected = true;
    },

    Deselected : function(obj) {
        obj.IsSelected = false;
    },

    SelectNone : function() {
        for (var i = 0; i < this.objects.length; ++i) {
            this.objects[i].IsSelected = false;
        }
    },

    SelectAll : function() {
        for (var i = 0; i < this.objects.length; ++i) {
            this.objects[i].IsSelected = true;
        }
    },

    ReverseSelect : function() {
        for (var i = 0; i < this.objects.length; ++i) {
            this.objects[i].IsSelected = !this.objects[i].IsSelected;
        }
    },

    IndexOf : function(obj) {
        if (!obj) {
            return -1;
        }

        var index = -1;
        for (var i = 0; i < this.objects.length; ++i) {
            if (this.objects[i] == obj) {
                index = i;
                break;
            }
        }

        return index;
    },

    MoveObjectUp : function(obj) {
        var index = this.IndexOf(obj);
        if (index != -1 && index < this.objects.length-1) {
            var objs = this.objects.splice(index, 2);
            this.objects.splice(index, 0, objs[1], objs[0]);
        }
    },

    MoveObjectTop : function(obj) {
        var index = this.IndexOf(obj);
        if (index != -1 && index != this.objects.lenght-1) {
            this.objects.push(this.objects.splice(index, 1)[0]);
        }
    },

    MoveObjectDown : function(obj) {
        var index = this.IndexOf(obj);
        if (index > 0) {
            --index;
            var objs = this.objects.splice(index, 2);
            this.objects.splice(index, 0, objs[1], objs[0]);
        }
    },

    MoveObjectBottom : function(obj) {
        var index = this.IndexOf(obj);
        if (index > 0) {
            this.objects.unshift(this.objects.splice(index, 1)[0]);
        }
    }
});
